<?php


namespace apps\marriage\app\mp\controller;


use apps\marriage\core\logic\WeixinMpLogic;
use apps\marriage\core\model\SubscribeMessageTemplate;
use apps\marriage\core\service\SiteConfigService;
use apps\marriage\core\service\SubscribeMessageTemplateService;
use apps\marriage\core\service\UserPlatformService;
use apps\marriage\core\service\UserService;
use think\Exception;
use think\facade\Log;
use think\Request;

class WechatController extends BaseMarriageMpController
{
    /**
     * @var WeixinMpLogic
     */
    private $weixinMpLogic;

    /**
     * @var UserPlatformService
     */
    private $userPlatformService;

    /**
     * @var UserService
     */
    private $userService;

    /**
     * @var SiteConfigService
     */
    private $siteConfigService;

    /**
     * @var SubscribeMessageTemplateService
     */
    private $subscribeMessageTemplateService;

    const QRCODE_TICKET_CACHE_PREFIX = 'wechat_qrcode_ticket:';

    protected function init()
    {
        parent::init();
        $this->weixinMpLogic = logic('WeixinMp', LOGIC_NAMESPACE);
        $this->userPlatformService = service('UserPlatform', SERVICE_NAMESPACE);
        $this->userService = service('User', SERVICE_NAMESPACE);
        $this->siteConfigService = service('SiteConfig', SERVICE_NAMESPACE);
        $this->subscribeMessageTemplateService = service('SubscribeMessageTemplate', SERVICE_NAMESPACE);
    }

    public function jsapi_config(Request $request)
    {
        $url = $request->param('url');
        $config = $this->weixinMpLogic->getApiClient()->get_jsapi_config($url);
        return $this->success($config);
    }

    public function wx_user_info_by_code(Request $request)
    {
        $code = $request->param('code');
        $res = $this->weixinMpLogic->getApiClient()->get_userinfo_by_authorize('snsapi_userinfo');
        Log::info(json_encode($res));
        $wxUserInfo = null;
        if($res[1]) {
            $res[1] = json_decode(json_encode($res[1]),TRUE);
            $wxUserInfo = arrayOnly($res[1], [
                'openid',
                'nickname',
                'headimgurl'
            ]);
            if(isset($res[1]['unionid'])) {
                $wxUserInfo['unionid'] = $res[1]['unionid'];
            } else {
                $wxUserInfo['unionid'] = '';
            }
        }
        return $this->success([
            'wx_user_info' => $wxUserInfo
        ]);
    }

    public function qrcode(Request $request)
    {
        $sceneId = $request->param('scene_id', 0);
        $ticket = cache(self::QRCODE_TICKET_CACHE_PREFIX . $sceneId);
        if(empty($ticket)) {
            $result = $this->weixinMpLogic->getApiClient()->create_qrcode($sceneId);
            if($result[1]) {
                $ticket = $result[1]->ticket;
                $expire_seconds = 2592000;
                cache(self::QRCODE_TICKET_CACHE_PREFIX . $sceneId, $ticket, $expire_seconds);
            }
        }
        if($ticket) {
            $qrcode = $this->weixinMpLogic->getApiClient()->get_qrcode_url($ticket);
        } else {
            $qrcode = '';
        }
        return $this->success(['qrcode' => $qrcode]);
    }

    public function create_menu(Request $request) {
        if(!$request->isCli()) {
            throw new Exception('is hack.');
        }
        $menus = [
            'button' => [
                [
                    'name' => '我是单身',
                    'sub_button' => [
                        [
                            'type' => 'view',
                            'name' => '缘分速配',
                            'url' => 'https://marriage.server.cn/mp'
                        ],
                        [
                            'type' => 'view',
                            'name' => '相亲活动',
                            'url' => 'https://marriage.server.cn/mp/activity_index'
                        ],
                        [
                            'type' => 'view',
                            'name' => '婚恋学院',
                            'url' => 'https://marriage.server.cn/mp/college_index'
                        ],
                        [
                            'type' => 'view',
                            'name' => '消息',
                            'url' => 'https://marriage.server.cn/mp/message_index'
                        ],
                        [
                            'type' => 'view',
                            'name' => '个人中心',
                            'url' => 'https://marriage.server.cn/mp/my_index'
                        ]
                    ]
                ],
                [
                    'name' => '我是红娘',
                    'sub_button' => [
                        [
                            'type' => 'view',
                            'name' => '我要分享',
                            'url' => 'https://marriage.server.cn/mp/matchmaker_index'
                        ],
                        [
                            'type' => 'view',
                            'name' => '我的收益',
                            'url' => 'https://marriage.server.cn/mp/my_matchmaker_index'
                        ],
                        [
                            'type' => 'view',
                            'name' => '我的推广',
                            'url' => 'https://marriage.server.cn/mp/my_matchmaker_index'
                        ],
                        [
                            'type' => 'view',
                            'name' => '专属二维码',
                            'url' => 'https://marriage.server.cn/mp/my_setting_index'
                        ]
                    ]
                ]
            ]
        ];
        $result = $this->weixinMpLogic->getApiClient()->create_menu(json_encode($menus, JSON_UNESCAPED_UNICODE));
        return $this->success(['result' => $result]);
    }

    public function gen_qrcode_scene_str(Request $request)
    {
        $appId = $request->param('app_id', 0, 'intval');
        $appToken = $request->param('app_token', '');
        $apiTokens = $this->siteConfigService->getValueByCode('api_tokens');
        if(!isset($apiTokens[$appId]) || $apiTokens[$appId] != $appToken) {
            throw new Exception('app id invalid');
        }
        $data = $request->param('data', '');
        $data = empty($data) ? null : json_decode($data, 1);
        $scene = $this->weixinMpLogic->genQrCodeSceneStr($data);
        $result = $this->weixinMpLogic->createQrCodeWithSceneStr($scene, 2592000);
        $qr = $this->weixinMpLogic->getApiClient()->get_qrcode_url($result['ticket']);
        return $this->success([
            'qr' => $qr
        ]);
    }

    public function feed(Request $request)
    {
        $params = $request->param();
        $postData = @file_get_contents('php://input');
        $postData = xmlToArray($postData);
        Log::info('params:' . json_encode($params));
        Log::info('postData:' . json_encode($postData));

        $timestamp = $params['timestamp'];
        $nonce = $params['nonce'];
        $signature = $params['signature'];
        if($this->weixinMpLogic->checkMsgSignature($signature, $nonce, $timestamp)) {
            if(isset($params['echostr'])) { // 接口验证
                $result = $params['echostr'];
            } else {
                $encryptType = $params['encrypt_type'];
                $msgSignature = $params['msg_signature'];
                $msg = $this->weixinMpLogic->decryptMsg($postData, $timestamp, $nonce, $encryptType, $msgSignature);
                $result = $this->msgHanlder($msg);
            }
        } else {
            $result = 'fail';
        }

        if (ob_get_level() == 0) {
            ob_start();
        }
        ob_implicit_flush(true);
        ob_clean();
        header("Content-type: text/plain");
        #log_msg(headers_list());
        echo($result);
        ob_flush();
        flush();
        ob_end_flush();
//        die();
    }

    private function msgHanlder(array $msg)
    {
        $result = 'success';
        if($msg['MsgType'] == 'event') {    // 事件通知
            $FromUserName = $msg['FromUserName'];
            if($msg['Event'] == 'subscribe') {  // 关注
                $this->userPlatformService->update([
                    'is_subscribed' => 1
                ], ['open_id' => $FromUserName]);

                if(isset($msg['EventKey']) && !empty($msg['EventKey'])) {   // 扫码后关注
                    $EventKey = $msg['EventKey'];   // 场景值
                    $scene = str_replace('qrscene_', '', $EventKey);
                    $data = $this->weixinMpLogic->decodeQrCodeScene($scene);
                    if($data) {
                        if($data['type'] == 'miniprogram' && $data['scan_from'] == 'quote_signin') {
                            $appId = $data['app_id'];
                            $path = $data['path'];
                            $result = arrayToXml([  // 转发到微信官方客服工具
                                'ToUserName' => $FromUserName,
                                'FromUserName' => $msg['ToUserName'],
                                'CreateTime' => time(),
                                'MsgType' => 'text',
                                'Content' => "打卡可以帮你记录每天起床睡觉时间，养成良好习惯。\r\n\r\n早起打卡时间：4:00-12:00\r\n\r\n早睡打卡时间：19:00-4:00\r\n\r\n点击链接开始打卡\r\n\r\n<a href=\"https://marriage.server.cn/mp\" data-miniprogram-appid=\"".$appId."\" data-miniprogram-path=\"".$path."\">早晚安打卡</a>"
                            ]);
                        }
                    }
                } else {
                    $result = arrayToXml([  // 发送图文消息
                        'ToUserName' => $FromUserName,
                        'FromUserName' => $msg['ToUserName'],
                        'CreateTime' => time(),
                        'MsgType' => 'text',
                        'Content' => "感谢您关注美恋婚恋系统，美恋婚恋系统是一个真实、严肃、高效的相亲交友平台，以帮助单身人士找到理想伴侣为己任。\r\n\r\n客服微信\r\n小北：a174674109\r\n\r\n关注视频号：\r\n#视频号：美恋婚恋系统\r\n\r\n美恋婚恋系统征婚平台：\r\nhttps://marriage.server.cn/mp"
                    ]);
                }
                // 发送客服消息
                $staticsUrl = $this->siteConfigService->getValueByCode('statics_url');
                $serviceMsg = [
                    'touser' => $FromUserName,
                    "msgtype" => "news",
                    'news' => [
                        'articles' => [
                            [
                                'title' => '美恋婚恋系统',
                                'description' => '汇集上万名优质单身人士，立即注册，早日找到幸福伴侣。',
                                'url' => 'https://marriage.server.cn/mp',
                                'picurl' => $staticsUrl . '/images/logo.png'
                            ]
                        ]
                    ]
                ];
                $this->weixinMpLogic->sendCustomServiceMessage($serviceMsg);

                $serviceMsg = [
                    'touser' => $FromUserName,
                    "msgtype" => "news",
                    'news' => [
                        'articles' => [
                            [
                                'title' => '免费领VIP会员',
                                'description' => '关注美恋婚恋系统公众号，免费领取VIP会员',
                                'url' => 'https://marriage.server.cn/mp/marketing_activity?id=1',
                                'picurl' => $staticsUrl . '/images/logo.png'
                            ]
                        ]
                    ]
                ];
                $this->weixinMpLogic->sendCustomServiceMessage($serviceMsg);

            } else if($msg['Event'] == 'unsubscribe') { // 取消关注
                $this->userPlatformService->update([
                    'is_subscribed' => 0
                ], ['open_id' => $FromUserName]);
            } else if ($msg['Event'] == 'subscribe_msg_popup_event') {  // 订阅通知
                $userPlatform = $this->userPlatformService->getByOpenid($FromUserName);
                if($userPlatform) {
                    $SubscribeMsgPopupEvent = $msg['SubscribeMsgPopupEvent'];
                    if(!isset($SubscribeMsgPopupEvent['List']['TemplateId'])) {
                        foreach ($SubscribeMsgPopupEvent['List'] as $item) {
                            if($item['SubscribeStatusString'] == 'accept') {
                                $this->subscribeMessageTemplateService->create([
                                    'user_id' => $userPlatform['user_id'],
                                    'openid' => $FromUserName,
                                    'type' => SubscribeMessageTemplate::TYPE_ONCE,
                                    'template_id' => $item['TemplateId'],
                                    'add_time' => time()
                                ]);
                            }
                        }
                    } else if(isset($SubscribeMsgPopupEvent['List']['TemplateId'])) {
                        if($SubscribeMsgPopupEvent['List']['SubscribeStatusString'] == 'accept') {
                            $this->subscribeMessageTemplateService->create([
                                'user_id' => $userPlatform['user_id'],
                                'openid' => $FromUserName,
                                'type' => SubscribeMessageTemplate::TYPE_ONCE,
                                'template_id' => $SubscribeMsgPopupEvent['List']['TemplateId'],
                                'add_time' => time()
                            ]);
                        }
                    }
                }
            } else if ($msg['Event'] == 'subscribe_msg_change_event') {  // 拒收通知
                $SubscribeMsgChangeEvent = $msg['SubscribeMsgChangeEvent'];
                foreach ($SubscribeMsgChangeEvent as $key => $item) {
                    if($item['SubscribeStatusString'] == 'reject') {
                        $this->subscribeMessageTemplateService->delete([
                            'openid' => $FromUserName,
                            'template_id' => $item['TemplateId']
                        ]);
                    }
                }
            } else if ($msg['Event'] == 'subscribe_msg_sent_event') {  // 发送通知结果
                $SubscribeMsgSentEvent = $msg['SubscribeMsgSentEvent'];
                foreach ($SubscribeMsgSentEvent as $key => $item) {
                    if($item['ErrorCode'] == 0) {
                        $this->subscribeMessageTemplateService->deleteEarliestTemplateIdByOpenid($FromUserName, $item['TemplateId'], SubscribeMessageTemplate::TYPE_ONCE);
                    }
                }
            } else if ($msg['Event'] == 'SCAN') {   // 扫描带参数二维码
                $EventKey = isset($msg['EventKey']) ? $msg['EventKey'] : '';   // 场景值
                $data = $this->weixinMpLogic->decodeQrCodeScene($EventKey);
                if($data) {
                    if($data['type'] == 'miniprogram' && $data['scan_from'] == 'quote_signin') {
                        $appId = $data['app_id'];
                        $path = $data['path'];
                        $result = arrayToXml([  // 转发到微信官方客服工具
                            'ToUserName' => $FromUserName,
                            'FromUserName' => $msg['ToUserName'],
                            'CreateTime' => time(),
                            'MsgType' => 'text',
                            'Content' => "打卡可以帮你记录每天起床睡觉时间，养成良好习惯。\r\n\r\n早起打卡时间：4:00-12:00\r\n\r\n早睡打卡时间：19:00-4:00\r\n\r\n点击链接开始打卡\r\n\r\n<a href=\"https://marriage.server.cn/mp\" data-miniprogram-appid=\"".$appId."\" data-miniprogram-path=\"".$path."\">早晚安打卡</a>"
                        ]);
                    }
                }
            }
        } else if($msg['MsgType'] == 'text') {  // 文本消息
            $ToUserName = $msg['ToUserName'];
            $FromUserName = $msg['FromUserName'];
            $content = $msg['Content'];
            if($content == '1') {   // 指令
                $dialog = cache(WxMiniLogic::DIALOG_CACHE_PREFIX . md5($FromUserName));
                if($dialog) {
                    if($dialog['opt'] == 'download_song') { //TODO: 下载单曲
                        $message = [
                            'touser' => $FromUserName,
                            'msgtype' => 'text',
                            'text' => [
                                'content' => '下载地址：https://www.baidu.com'
                            ]
                        ];
                        $this->wxMiniLogic->sendCustomServiceMessage($message);
                    }
                }
            } else {
                $result = arrayToXml([  // 转发到微信官方客服工具
                    'ToUserName' => $FromUserName,
                    'FromUserName' => $ToUserName,
                    'CreateTime' => time(),
                    'MsgType' => 'transfer_customer_service'
                ]);
            }
        }
        return $result;
    }
}